/**
 * 
 */
package org.pump.client.codec;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.mina.core.buffer.IoBuffer;
import org.pump.client.type.LengthCodedBinary;
import org.pump.client.type.MysqlType;
import org.pump.client.type.NullTerminatedString;
import org.pump.client.type.Varstr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author liudong03
 *
 */
public class TableMapEvent extends EventData{
	private static final Logger mylog = LoggerFactory.getLogger(TableMapEvent.class);
	long table_id ;
	byte[] flags = new byte[2];
	Varstr database_name;
	Varstr table_name;
	LengthCodedBinary column_count;
	List<Short> column_type;
	LengthCodedBinary metadata_length;
	List<byte[]> metadata;
	byte[] null_bits;
	int length;
	
	/**
	 * 
	 */
	public TableMapEvent() {
		// TODO Auto-generated constructor stub
		this.column_type = new ArrayList<Short>();
		this.metadata = new ArrayList<byte[]>();
	}
	
	public static TableMapEvent readBuffer(IoBuffer in,int len)
	{
		if(in.remaining() < len)
		{
			return null;
		}
		TableMapEvent myevent = new TableMapEvent();
		long temp = 0;
		for(int i = 0; i < 6; i++)
		{
			temp = in.getUnsigned()  << (i *8);
			myevent.table_id += temp;
		}
		myevent.length += 6;
		in.get(myevent.flags);
		myevent.length += 2;
		
		myevent.database_name = Varstr.readBuffer1(in, "GBK");
		myevent.length += myevent.database_name.getSize1();
		myevent.table_name = Varstr.readBuffer1(in, "GBK");
		myevent.length += myevent.table_name.getSize1();
		
		myevent.column_count = LengthCodedBinary.readBuffer(in);
		myevent.length += myevent.column_count.getLen();
		
		long colcount = myevent.column_count.getData();
		for(short i = 0; i < colcount; i++)
		{
			short cur_col_type = in.getUnsigned();
			myevent.length ++;
			myevent.column_type.add(new Short(cur_col_type));
		}
		
		myevent.metadata_length = LengthCodedBinary.readBuffer(in);
		myevent.length += myevent.column_count.getLen();
		
		for(Short id : myevent.column_type)
		{
			short metasize = MysqlType.getMetasize(id.shortValue());
			if(metasize == 0) 
			{
				myevent.metadata.add(null);
				continue;
			}
			byte[] cur_id_meta = new byte[metasize];
			in.get(cur_id_meta);
			myevent.length += metasize;
			myevent.metadata.add(cur_id_meta);
		}
		
		int null_bits_len = (int)(colcount+7)>>3;
		myevent.null_bits = new byte[null_bits_len];
		in.get(myevent.null_bits);
		myevent.length += null_bits_len;
		
		if(myevent.length != len)
		{
			mylog.error("the length is not match");
			return null;
		}
		return myevent;
	}

	

	

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "TableMapEvent [table_id=" + table_id + ", flags="
				+ Arrays.toString(flags) + ", database_name=" + database_name
				+ ", table_name=" + table_name + ", column_count="
				+ column_count + ", column_type=" + column_type
				+ ", metadata_length=" + metadata_length + ", metadata="
				+ metadata + ", null_bits=" + Arrays.toString(null_bits)
				+ ", length=" + length + "]";
	}

	/**
	 * @return the mylog
	 */
	public static Logger getMylog() {
		return mylog;
	}

	/**
	 * @return the table_id
	 */
	public long getTable_id() {
		return table_id;
	}

	/**
	 * @return the flags
	 */
	public byte[] getFlags() {
		return flags;
	}

	/**
	 * @return the database_name
	 */
	public String getDatabase_name() {
		return database_name.getStrContent();
	}

	/**
	 * @return the table_name
	 */
	public String getTable_name() {
		return table_name.getStrContent();
	}

	/**
	 * @return the column_count
	 */
	public LengthCodedBinary getColumn_count() {
		return column_count;
	}

	/**
	 * @return the column_type
	 */
	public List<Short> getColumn_type() {
		return column_type;
	}

	/**
	 * @return the metadata_length
	 */
	public LengthCodedBinary getMetadata_length() {
		return metadata_length;
	}

	/**
	 * @return the metadata
	 */
	public List<byte[]> getMetadata() {
		return metadata;
	}

	/**
	 * @return the null_bits
	 */
	public byte[] getNull_bits() {
		return null_bits;
	}

	/**
	 * @return the length
	 */
	public int getLength() {
		return length;
	}
	
	

}
